﻿using Furion.DatabaseAccessor;
using Furion.DependencyInjection;
using Furion.DynamicApiController;
using Furion.FriendlyException;
using iWare.Wms.Core;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System.Linq.Dynamic.Core;

namespace iWare.Wms.Application
{
    /// <summary>
    /// Agv任务服务
    /// </summary>
    [Route("api/WareAgvTask")]
    [ApiDescriptionSettings("仓库基础数据", Name = "WareAgvTask", Order = 100)]

    public class WareAgvTaskService : IDynamicApiController, ITransient
    {
        private readonly IRepository<WareLocationVsContainer, MasterDbContextLocator> _wareLocationVsContainerRep; //库位容器仓储
        private readonly IRepository<WareAgvTask, MasterDbContextLocator> _wareAgvTaskRep; //AGV任务仓储
        private readonly IRepository<WareContainer, MasterDbContextLocator> _wareContainerRep; //容器仓储
        private readonly IRepository<WareLocation, MasterDbContextLocator> _wareLocationRep; //容器仓储
        private readonly IRepository<WareTask, MasterDbContextLocator> _wareTaskRep; //任务仓储
        private readonly IRepository<WareContainerVsMaterial, MasterDbContextLocator> _wareContainerVsMaterialRep; //容器与物料关系仓储

        #region 默认
        /// <summary>
        /// 默认
        /// </summary>
        /// <param name="wareLocationVsContainerRep"></param>
        /// <param name="stereoscopicServer"></param>
        /// <param name="wareAgvTaskRep"></param>
        /// <param name="wareContainerRep"></param>
        /// <param name="wareLocationRep"></param>
        /// <param name="wareTaskRep"></param>
        /// <param name="wareContainerVsMaterialRep"></param>
        public WareAgvTaskService(
           IRepository<WareLocationVsContainer, MasterDbContextLocator> wareLocationVsContainerRep,
           IRepository<WareAgvTask, MasterDbContextLocator> wareAgvTaskRep,
           IRepository<WareContainer, MasterDbContextLocator> wareContainerRep,
           IRepository<WareLocation, MasterDbContextLocator> wareLocationRep,
           IRepository<WareTask, MasterDbContextLocator> wareTaskRep,
           IRepository<WareContainerVsMaterial, MasterDbContextLocator> wareContainerVsMaterialRep
        )
        {
            _wareLocationVsContainerRep = wareLocationVsContainerRep;
            _wareAgvTaskRep = wareAgvTaskRep;
            _wareContainerRep = wareContainerRep;
            _wareLocationRep = wareLocationRep;
            _wareTaskRep = wareTaskRep;
            _wareContainerVsMaterialRep = wareContainerVsMaterialRep;
        }
        #endregion

        /// <summary>
        /// 分页查询AGV任务
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpGet("Page")]
        public async Task<PageResult<WareAgvTaskOutput>> Page([FromQuery] WareAgvTaskSearch input)
        {
            var list = await _wareAgvTaskRep.DetachedEntities
                .Where(!string.IsNullOrEmpty(input.TaskType) && input.TaskType != "全部", u => u.TaskType == input.TaskType)
                .Where(!string.IsNullOrEmpty(input.StartPlace), u => u.StartPlace == input.StartPlace)
                .Where(!string.IsNullOrEmpty(input.EndPlace), u => u.EndPlace == input.EndPlace)
                .Where(!string.IsNullOrEmpty(input.AgvState) && input.TaskType != "全部", u => u.AgvState == input.AgvState)
                .Where(!string.IsNullOrEmpty(input.ContainerCode), u => u.ContainerCode == input.ContainerCode)
                .Where(!string.IsNullOrEmpty(input.TransportOrder), u => u.TransportOrder == input.TransportOrder)
                .Where(!string.IsNullOrEmpty(input.CreatedUserName), u => EF.Functions.Like(u.CreatedUserName, $"%{input.CreatedUserName.Trim()}%"))
                .Where(!string.IsNullOrEmpty(input.SearchBeginTime), u => u.CreatedTime >= DateTime.Parse(input.SearchBeginTime.Trim()) &&
                 u.CreatedTime <= DateTime.Parse(input.SearchEndTime.Trim()))
                .OrderBy(PageInputOrder.OrderBuilder(input))
                .ProjectToType<WareAgvTaskOutput>()
                .ToADPagedListAsync(input.PageNo, input.PageSize);

            foreach (var item in list.Rows)
            {
                if (item.TaskType == "入库")
                {
                    var wareAgv = await _wareLocationRep.FirstOrDefaultAsync(z => z.Code == item.StartPlace);
                    if (wareAgv != null)
                    {
                        item.StartPlaceCode = wareAgv != null ? wareAgv.Code : "";
                        item.EndPlaceCode = "";
                    }
                }
                else if(item.TaskType == "出库")
                {
                    var wareAgv = await _wareLocationRep.FirstOrDefaultAsync(z => z.Code == item.EndPlace);
                    if (wareAgv != null)
                    {
                        item.EndPlaceCode = wareAgv != null ? wareAgv.Code : "";
                        item.StartPlaceCode = "";
                    }
                }
                else if(item.TaskType == "余料回库")
                {
                    var wareAgv = await _wareLocationRep.FirstOrDefaultAsync(z => z.Code == item.StartPlace);
                    if (wareAgv != null)
                    {
                        item.StartPlaceCode = wareAgv != null ? wareAgv.Code : "";
                        item.EndPlaceCode = "";
                    }
                }
            }

            return list;
        }

        /// <summary>
        /// 新增AGV任务
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("add")]
        [NonAction]
        public async Task Add(AddWareAgvTaskInput input)
        {
            var isExist = await _wareAgvTaskRep.DetachedEntities.AnyAsync(u => u.TransportOrder == input.TransportOrder && u.ContainerCode == input.ContainerCode);
            if (isExist) throw Oops.Oh("数据已存在");

            var wareAgvTask = input.Adapt<WareAgvTask>();
            await _wareAgvTaskRep.InsertAsync(wareAgvTask);
        }

        /// <summary>
        /// 删除AGV任务
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("delete")]
        public async Task Delete([FromBody] DeleteWareAgvTaskInput input)
        {
            int length = input.Id.Count;
            for (int i = 0; i < length; i++)
            {
                long Id = input.Id[i];
                var wareAgvTask = await _wareAgvTaskRep.FirstOrDefaultAsync(u => u.Id == Id);
                await _wareAgvTaskRep.DeleteAsync(wareAgvTask);
            }
        }

        /// <summary>
        /// 更新AGV任务
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("edit")]
        [NonAction]
        public async Task Update([FromBody] UpdateWareAgvTaskInput input)
        {
            var isExist = await _wareAgvTaskRep.AnyAsync(u => u.Id == input.Id, false);
            if (!isExist) throw Oops.Oh("数据不存在");

            var wareAgvTask = input.Adapt<WareAgvTask>();
            await _wareAgvTaskRep.UpdateAsync(wareAgvTask, ignoreNullValues: true);
        }
    }
}

